package com.situ.shoplook.common.util;

import java.io.Serializable;
import java.util.AbstractList;
import java.util.List;
import java.util.RandomAccess;

/**
 * 功能：
 *
 * @author 千堆雪
 * @version 1.0.0
 * <p>
 * created by 千堆雪 on 2024/8/25, last modified by 千堆雪 on 2024/8/25
 */
public interface PaginateParams extends Serializable {
    int getPageNo();

    int getPageSize();

    static PaginateParams empty() {
        return PaginateInfo.empty();
    }

    static PaginateParams of(int pageNo, int pageSize) {
        return PaginateInfo.of(pageNo, pageSize);
    }

    //分页参数响应接口
    interface PaginateResponse<T> extends PaginateParams {
        int getTotal();

        int getPages();

        List<T> getData();
    }

    //分页参数响应实体
    record PaginateInfo<T>(int pageNo, int pageSize, int total, int pages,
                           List<T> data) implements PaginateResponse<T> {
        private static final PaginateInfo<?> EMPTY = of(1, Integer.MAX_VALUE);
        private static final ThreadLocal<Object> threadLocal = new ThreadLocal<>();

        //设置本地线程变量
        public static <T> void setPaginateInfo(PaginateInfo<T> info) {
            threadLocal.set(info);
        }

        //取出并移除
        @SuppressWarnings("unchecked")
        public static <T> PaginateInfo<T> getPaginateInfo() {
            PaginateInfo<T> info = (PaginateInfo<T>) threadLocal.get();
            threadLocal.remove();
            return info;
        }

        public static <T> PaginateInfo<T> of(int pageNo, int pageSize) {
            return new PaginateInfo<>(pageNo, pageSize, 0, 0, null);
        }


        public static PaginateInfo<?> empty() {
            return EMPTY;
        }

        public PaginatedList<T> paginatedList(List<T> data) {
            return new PaginatedList<>(data, this);
        }

        @Override
        public int getPageNo() {
            return this.pageNo();
        }

        @Override
        public int getPageSize() {
            return this.pageSize();
        }

        @Override
        public int getTotal() {
            return this.total();
        }

        @Override
        public int getPages() {
            return this.pages();
        }

        @Override
        public List<T> getData() {
            return null;
        }


    }

    class PaginatedList<T> extends AbstractList<T> implements PaginateResponse<T>, RandomAccess, Serializable {
        private final List<T> list;
        private final PaginateInfo<T> pi;

        public PaginatedList(List<T> list, PaginateInfo<T> pi) {
            this.list = list;
            this.pi = pi;
        }

        @Override
        public T set(int index, T element) {
            return list.set(index, element);
        }

        @Override
        public void add(int index, T element) {
            list.add(index, element);
        }

        @Override
        public T remove(int index) {
            return list.remove(index);
        }

        @Override
        public T get(int index) {
            return list.get(index);
        }

        @Override
        public int size() {
            return list.size();
        }

        @Override
        public int getTotal() {
            return this.pi.getTotal();
        }

        @Override
        public int getPages() {
            return this.pi.getPages();
        }

        @Override
        public List<T> getData() {
            return this.pi.getData();
        }

        @Override
        public int getPageNo() {
            return this.pi.getPageNo();
        }

        @Override
        public int getPageSize() {
            return this.pi.getPageSize();
        }
    }
}
